热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

附源码|paddlepaddle实现猫狗识别

本文是基于paddlepaddle采用CNN实现猫狗识别案例。author:小黄缓慢而坚定的生长图像分类是根据图像的语义信息将不同类别图像区分开来,是计

本文是基于paddle paddle采用CNN实现猫狗识别案例。



author:小黄
缓慢而坚定的生长



图像分类是根据图像的语义信息将不同类别图像区分开来,是计算机视觉中重要的基本问题

猫狗分类属于图像分类中的粗粒度分类问题


step1.数据准备

#导入需要的包
import paddle as paddle
import paddle.fluid as fluid
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
import os

(1)数据集介绍

我们使用CIFAR10数据集。CIFAR10数据集包含60,000张32x32的彩色图片,10个类别,每个类包含6,000张。其中50,000张图片作为训练集,10000张作为验证集。这次我们只对其中的猫和狗两类进行预测。

(2)train_reader和test_reader

paddle.dataset.cifar.train10()和test10()分别获取cifar训练集和测试集

paddle.reader.shuffle()表示每次缓存BUF_SIZE个数据项,并进行打乱

paddle.batch()表示每BATCH_SIZE组成一个batch

(3)数据集下载

由于本次实践的数据集稍微比较大,以防出现不好下载的问题,为了提高效率,可以用下面的代码进行数据集的下载。

#!mkdir -p /home/aistudio/.cache/paddle/dataset/cifar/

#!wget “http://ai-atest.bj.bcebos.com/cifar-10-python.tar.gz” -O cifar-10-python.tar.gz

#!mv cifar-10-python.tar.gz /home/aistudio/.cache/paddle/dataset/cifar/

BATCH_SIZE = 128
#用于训练的数据提供器
train_reader = paddle.batch(paddle.reader.shuffle(paddle.dataset.cifar.train10(), buf_size=BATCH_SIZE * 100), batch_size=BATCH_SIZE)
#用于测试的数据提供器
test_reader = paddle.batch(paddle.dataset.cifar.test10(), batch_size=BATCH_SIZE)

Step2.网络配置

(1)网络搭建

在CNN模型中,卷积神经网络能够更好的利用图像的结构信息。下面定义了一个较简单的卷积神经网络。显示了其结构:输入的二维图像,先经过两次卷积层到池化层,再经过全连接层,最后使用softmax分类作为输出层。

池化是非线性下采样的一种形式,主要作用是通过减少网络的参数来减小计算量,并且能够在一定程度上控制过拟合。通常在卷积层的后面会加上一个池化层。paddlepaddle池化默认为最大池化。是用不重叠的矩形框将输入层分成不同的区域,对于每个矩形框的数取最大值作为输出

在这里插入图片描述

def convolutional_neural_network(img):# 第一个卷积-池化层conv_pool_1 = fluid.nets.simple_img_conv_pool(input=img, # 输入图像filter_size=5, # 滤波器的大小num_filters=20, # filter 的数量。它与输出的通道相同pool_size=2, # 池化核大小2*2pool_stride=2, # 池化步长act="relu") # 激活类型# 第二个卷积-池化层conv_pool_2 = fluid.nets.simple_img_conv_pool(input=conv_pool_1,filter_size=5,num_filters=50,pool_size=2,pool_stride=2,act="relu")# 以softmax为激活函数的全连接输出层,10类数据输出10个数字prediction = fluid.layers.fc(input=conv_pool_2, size=10, act='softmax')return prediction

(2)定义数据

#定义输入数据
data_shape = [3, 32, 32]
images = fluid.layers.data(name='images', shape=data_shape, dtype='float32')
label = fluid.layers.data(name='label', shape=[1], dtype='int64')

(3)获取分类器

# 获取分类器,用cnn进行分类
predict = convolutional_neural_network(images

(4)定义损失函数和准确率

这次使用的是交叉熵损失函数,该函数在分类任务上比较常用。

定义了一个损失函数之后,还有对它求平均值,因为定义的是一个Batch的损失值。

同时我们还可以定义一个准确率函数,这个可以在我们训练的时候输出分类的准确率。

# 获取损失函数和准确率
cost = fluid.layers.cross_entropy(input=predict, label=label) # 交叉熵
avg_cost = fluid.layers.mean(cost) # 计算cost中所有元素的平均值
acc = fluid.layers.accuracy(input=predict, label=label) #使用输入和标签计算准确率

(5)定义优化方法

这次我们使用的是Adam优化方法,同时指定学习率为0.001

# 定义优化方法
optimizer =fluid.optimizer.Adam(learning_rate=0.001)
optimizer.minimize(avg_cost)
print("完成")

在上述模型配置完毕后,得到两个fluid.Program:fluid.default_startup_program() 与fluid.default_main_program() 配置完毕了。

参数初始化操作会被写入fluid.default_startup_program()

fluid.default_main_program()用于获取默认或全局main program(主程序)。该主程序用于训练和测试模型。fluid.layers 中的所有layer函数可以向 default_main_program 中添加算子和变量。default_main_program 是fluid的许多编程接口(API)的Program参数的缺省值。例如,当用户program没有传入的时候, Executor.run() 会默认执行 default_main_program 。


Step3.模型训练 and Step4.模型评估

(1)创建Executor

首先定义运算场所 fluid.CPUPlace()和 fluid.CUDAPlace(0)分别表示运算场所为CPU和GPU

Executor:接收传入的program,通过run()方法运行program。

place = fluid.CPUPlace()
exe = fluid.Executor(place)
exe.run(fluid.default_startup_program())

(2)定义数据映射器

DataFeeder 负责将reader(读取器)返回的数据转成一种特殊的数据结构,使它们可以输入到 Executor

feeder = fluid.DataFeeder( feed_list=[images, label],place=place)

(3)定义绘制训练过程的损失值和准确率变化趋势的方法draw_train_process

iter=0
iters=[]
train_costs=[]
train_accs=[]
def draw_train_process(iters, train_costs, train_accs):title="training costs/training accs"plt.title(title, fontsize=24)plt.xlabel("iter", fontsize=14)plt.ylabel("cost/acc", fontsize=14)plt.plot(iters, train_costs, color='red', label='training costs')plt.plot(iters, train_accs, color='green', label='training accs')plt.legend()plt.grid()plt.show()

(3)训练并保存模型

Executor接收传入的program,并根据feed map(输入映射表)和fetch_list(结果获取表) 向program中添加feed operators(数据输入算子)和fetch operators(结果获取算子)。 feed map为该program提供输入数据。fetch_list提供program训练结束后用户预期的变量。

每一个Pass训练结束之后,再使用验证集进行验证,并打印出相应的损失值cost和准确率acc。

EPOCH_NUM = 3
model_save_dir = "/home/aistudio/data/catdog.inference.model"for pass_id in range(EPOCH_NUM):# 开始训练train_cost = 0for batch_id, data in enumerate(train_reader()): #遍历train_reader的迭代器,并为数据加上索引batch_idtrain_cost,train_acc = exe.run(program=fluid.default_main_program(),#运行主程序feed=feeder.feed(data), #喂入一个batch的数据fetch_list=[avg_cost, acc]) #fetch均方误差和准确率if batch_id % 100 == 0: #每100次batch打印一次训练、进行一次测试print('Pass:%d, Batch:%d, Cost:%0.5f, Accuracy:%0.5f' % (pass_id, batch_id, train_cost[0], train_acc[0]))iter=iter+BATCH_SIZEiters.append(iter)train_costs.append(train_cost[0])train_accs.append(train_acc[0])# 开始测试test_costs = [] #测试的损失值test_accs = [] #测试的准确率for batch_id, data in enumerate(test_reader()):test_cost, test_acc = exe.run(program=fluid.default_main_program(), #运行测试程序feed=feeder.feed(data), #喂入一个batch的数据fetch_list=[avg_cost, acc]) #fetch均方误差、准确率test_costs.append(test_cost[0]) #记录每个batch的误差test_accs.append(test_acc[0]) #记录每个batch的准确率test_cost = (sum(test_costs) / len(test_costs)) #计算误差平均值(误差和/误差的个数)test_acc = (sum(test_accs) / len(test_accs)) #计算准确率平均值( 准确率的和/准确率的个数)print('Test:%d, Cost:%0.5f, ACC:%0.5f' % (pass_id, test_cost, test_acc))#保存模型if not os.path.exists(model_save_dir):os.makedirs(model_save_dir)fluid.io.save_inference_model(model_save_dir,['images'],[predict],exe)
print('训练模型保存完成!')
draw_train_process(iters, train_costs,train_accs)

Step5.模型预测

(1)创建预测用的Executor

infer_exe = fluid.Executor(place)
inference_scope = fluid.core.Scope()

(2)图片预处理

在预测之前,要对图像进行预处理。

首先将图片大小调整为32*32,接着将图像转换成一维向量,最后再对一维向量进行归一化处理。

def load_image(file):#打开图片im = Image.open(file)im = im.convert('RGB')#将图片调整为跟训练数据一样的大小 32*32, 设定ANTIALIAS,即抗锯齿.resize是缩放im = im.resize((32, 32), Image.ANTIALIAS)#建立图片矩阵 类型为float32im = np.array(im).astype(np.float32)#矩阵转置 im = im.transpose((2, 0, 1)) #将像素值从【0-255】转换为【0-1】im = im / 255.0#print(im) im = np.expand_dims(im, axis=0)# 保持和之前输入image维度一致print('im_shape的维度:',im.shape)return im

(3)开始预测

通过fluid.io.load_inference_model,预测器会从params_dirname中读取已经训练好的模型,来对从未遇见过的数据进行预测。

with fluid.scope_guard(inference_scope):#从指定目录中加载 推理model(inference model)[inference_program, # 预测用的programfeed_target_names, # 是一个str列表,它包含需要在推理 Program 中提供数据的变量的名称。 fetch_targets] = fluid.io.load_inference_model(model_save_dir,#fetch_targets:是一个 Variable 列表,从中我们可以得到推断结果。infer_exe) #infer_exe: 运行 inference model的 executorinfer_path='/home/aistudio/data/dog.png'img = Image.open(infer_path)plt.imshow(img) plt.show() img = load_image(infer_path)results = infer_exe.run(inference_program, #运行预测程序feed={feed_target_names[0]: img}, #喂入要预测的imgfetch_list=fetch_targets) #得到推测结果print('results',results)label_list = ["airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse","ship", "truck"]print("infer results: %s" % label_list[np.argmax(results[0])])

推荐阅读
  • 也就是|小窗_卷积的特征提取与参数计算
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 本文介绍了使用Spark实现低配版高斯朴素贝叶斯模型的原因和原理。随着数据量的增大,单机上运行高斯朴素贝叶斯模型会变得很慢,因此考虑使用Spark来加速运行。然而,Spark的MLlib并没有实现高斯朴素贝叶斯模型,因此需要自己动手实现。文章还介绍了朴素贝叶斯的原理和公式,并对具有多个特征和类别的模型进行了讨论。最后,作者总结了实现低配版高斯朴素贝叶斯模型的步骤。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • Ihavethefollowingonhtml我在html上有以下内容<html><head><scriptsrc..3003_Tes ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • Imtryingtofigureoutawaytogeneratetorrentfilesfromabucket,usingtheAWSSDKforGo.我正 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 本文介绍了在CentOS 6.4系统中更新源地址的方法,包括备份现有源文件、下载163源、修改文件名、更新列表和系统,并提供了相应的命令。 ... [详细]
  • 解决Sharepoint 2013运行状况分析出现的“一个或多个服务器未响应”问题的方法
    本文介绍了解决Sharepoint 2013运行状况分析中出现的“一个或多个服务器未响应”问题的方法。对于有高要求的客户来说,系统检测问题的存在是不可接受的。文章详细描述了解决该问题的步骤,包括删除服务器、处理分布式缓存留下的记录以及使用代码等方法。同时还提供了相关关键词和错误提示信息,以帮助读者更好地理解和解决该问题。 ... [详细]
author-avatar
图片哪天能显示
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有